// // // // let person = new Object();
// // // // person.name = 'Alice';
// // // // person.show = function(){
// // // //     console.log(this.name);
// // // // }
// // // // person.show();//Alice
// // // // console.log('------------------------------------------------------');
// // // // let student = {};
// // // // student.age = 24;
// // // // Object.defineProperty(student,'name',{
// // // //     value: 'Alice', //属性值为Alice
// // // //     //在非严格模式下尝试给这个属性重新赋值会被忽略。在严格模式下，尝试修改只读属性的值会抛出错误。
// // // //     writable: false, //该属性不可被修改。
// // // // });
// // // // Object.defineProperty(student,'grade',{
// // // //     value:'90',
// // // //     writable: true //注意当手动添加描述符对象的时候，其余的描述符对象都被覆盖成了false
// // // // })
// // // // console.log(student);//{ age: 24 }
// // // // console.log(student.age);//24
// // // // console.log(student.name);//Alice
// // // // console.log(student.grade);//90
// // // // student.name = 'Smith';
// // // // student.grade = 100;
// // // // console.log(student.name);//Alice
// // // // console.log(student.grade);//100

// // // // let teacher = {};
// // // // Object.defineProperty(teacher,'name',{
// // // //     value:'王老师',
// // // //     configurable:false //设置为不可配置 1.此时对该对象的name属性的任何配置都将不起作用
// // // // })
// // // // console.log(teacher);//{}
// // // // console.log(teacher.name);//王老师
// // // // teacher.name = '李老师'
// // // // console.log(teacher.name);//王老师
// // // // Object.defineProperty(teacher,'name',{
// // // //     value:'周老师' //TypeError: Cannot redefine property: name
// // // // })
// // // // Object.defineProperty(teacher,'name',{
// // // //     writable:true,
// // // //     value:'周老师' //TypeError: Cannot redefine property: name
// // // // })
// // // // Object.defineProperty(teacher,'name',{
// // // //     configurable:true//TypeError: Cannot redefine property: name
// // // // })
// // // // Object.defineProperty(teacher,'name',{
// // // //     writable:true,
// // // // })

// // // //1.验证
// // // //在调用 Object.defineProperty()时，configurable、enumerable 和 writable 的值如果不指定，则都默认为 false。
// // // // let student = {};
// // // // Object.defineProperty(student,'name',{
// // // //     value:'Alice',
// // // //     writable:true
// // // // })
// // // // console.log(student);//{}
// // // // console.log(student.name);//Alice
// // // // student.name = 'Smith';
// // // // console.log(student.name);//Alice
// // // // delete student.name;
// // // // console.log(student.name);//Alice
// // // // // Object.defineProperty(student,'name',{ //TypeError: Cannot redefine property: name,及时重新设置value:Smith也报错。
// // // // //     value:'Smith'
// // // // // })
// // // // Object.defineProperty(student,'name',{ //正常，因为即使重新defineProperty，也没有改变writable的值，默认为false
// // // //     writable:false
// // // // })
// // // // // Object.defineProperty(student,'name',{ //TypeError: Cannot redefine property: name
// // // // //     writable:true
// // // // // })
// // // // console.log(student.name);//Alice



// // // // let student = {};
// // // // Object.defineProperty(student,'name',{})
// // // // console.log(student.name);//undefined
// // // // student.name = 'Alice';
// // // // console.log(student.name);//undefined
// // // // // Object.defineProperty(student,'name',{ TypeError: Cannot redefine property: name
// // // // //     value:'Smith'
// // // // // })
// // // // // Object.defineProperty(student,'name',{ TypeError: Cannot redefine property: name
// // // // //     writable:true
// // // // // })
// // // // Object.defineProperty(student,'name',{
// // // //     writable:false
// // // // })
// // // // student.name = 'Alice';
// // // // console.log(student.name);//undefined

// // // // let student = { name: 'Alice'};
// // // // console.log(student.name);//Alice
// // // // student.name = 'Smith';//smith
// // // // console.log(student.name);
// // // // Object.defineProperty(student,'name',{
// // // //     configurable:false
// // // // })
// // // // student.name = 'Tom';
// // // // console.log(student.name);//Tom
// // // // delete student.name
// // // // console.log(student.name);//Tom

// // // // let obj = {};
// // // // Object.defineProperty(obj,'year',{
// // // //     configurable:true,
// // // //     value:2021
// // // // })
// // // // Object.defineProperty(obj,'score',{
// // // //     configurable:true,
// // // //     value:'89'
// // // // });
// // // // Object.defineProperty(obj,'rank',{
// // // //     get(){
// // // //         return this.rank;
// // // //     },
// // // //     set(newVal){
// // // //         if(newVal > 2018){
// // // //             this.score += this.rank - 2018;
// // // //         }
// // // //     }
// // // // })
// // // // console.log(obj.year);//2021
// // // // console.log(obj.score);//89
// // // // obj.rank = 2020;
// // // // console.log(obj.rank);
// // // // console.log(obj.score);

// // // let obj = {
// // //     privateNum:'',
// // //     edition:1
// // // }
// // // Object.defineProperty(obj,'year',{
// // //     get(){
// // //         console.log('getter----');
// // //         return this.privateNum;
// // //     },
// // //     set(newVal){
// // //         if(newVal > 2020){
// // //             console.log('setter----');
// // //             this.privateNum = newVal + 10;
// // //             this.edition += newVal - 2020;
// // //         }
// // //     }
// // // })
// // // obj.year = 2021;
// // // console.log(obj);//{ privateNum: 2031, edition: 2 }
// // // // setter----
// // // // { privateNum: 2031, edition: 2 }
// // // obj.year = 2022;
// // // console.log(obj.year);
// // // // setter----
// // // // getter----
// // // // 2032

// // let book = {};
// // Object.defineProperties(book,{
// //     name:{
// //         value:'哈利波特'
// //     },
// //     price:{
// //         value:'78.00',
// //         writable:true
// //     },
// //     year_:{
// //         value:'2019'
// //     },
// //     year:{
// //         get(){
// //             console.log('getter----');
// //             return '出版日期:'+ this.year_;
// //         },
// //         set(newValue){
// //             console.log('setter----');
// //             this.year_ =  newValue;
// //             if(newValue > 2000){
// //              this.price = Number(this.price) + Number(newValue - 2000);
// //             }
// //         }
// //     }
// // });
// // console.log(book);
// // console.log(book.name);//哈利波特
// // book.name = 'Silly'
// // console.log(book.name);//哈利波特
// // console.log(book.price);//78.00
// // book.price = '89.00';
// // console.log(book.price);//89.00
// // book.year = '2020';
// // // setter----
// // console.log(book.price);//109 
// // console.log(book.year);
// // // getter----
// // // 出版日期:2019

// let book = {}
// Object.defineProperties(book,{
//     name:{
//         value:'哈利波特与黑魔法石'
//     },
//     price_:{
//         value:'89.00',
//         writable:true
//     },
//     price:{
//         get(){
//             return '价格是:' + this.price_;
//         },
//         set(newValue){
//            this.price_ = newValue;
//         }
//     }
// })
// console.log(book.name);//哈利波特与黑魔法石
// console.log(book.price);//价格是:89.00
// book.price = '109.00';
// console.log(book.price);//价格是:109.00
// //--------------------------------------------------
// let dataDescriptor = Object.getOwnPropertyDescriptor(book,'price_');
// console.log(dataDescriptor.value); //109.00
// console.log(dataDescriptor.configurable);//false
// console.log(dataDescriptor.writable); //true
// console.log(dataDescriptor.enumerable);//false
// console.log(typeof dataDescriptor.get);//undefined
// let dataDescriptor1 = Object.getOwnPropertyDescriptor(book,'price');
// console.log(dataDescriptor1.value); //undefined
// console.log(dataDescriptor1.configurable);//false
// console.log(dataDescriptor1.writable); //undefined
// console.log(dataDescriptor1.enumerable);//false
// console.log(typeof dataDescriptor1.get);//function

// let descriptor = Object.getOwnPropertyDescriptors(book)
// console.log(descriptor);

// // {
// //     name: {
// //       value: '哈利波特与黑魔法石',
// //       writable: false,
// //       enumerable: false,
// //       configurable: false
// //     },
// //     price_: {
// //       value: '109.00',
// //       writable: true,
// //       enumerable: false,
// //       configurable: false
// //     },
// //     price: {
// //       get: [Function: get],
// //       set: [Function: set],
// //       enumerable: false,
// //       configurable: false
// //     }
// //   }

// let dest = {};
// let src = {src:1}
// let result = Object.assign(dest,src);
// console.log(result === dest); //true
// console.log(dest !== src); //true
// console.log(dest); //{ src:1 }
// console.log(src); //{ src:1 }
// console.log(result);//{ src:1 }
// let result1 = Object.assign(result,{foo:'foo'},{bar:'bar'});
// console.log(result1);//{ src: 1, foo: 'foo', bar: 'bar' }

// let dest = {
//     set a(val){
//         console.log(`invoked dest setter with param ${val}`);
//     }
// };
// let src = {
//     get a(){
//         console.log('invoked src getter a');
//         return 'foo';
//     },
//     get b(){
//         console.log('invoked src getter b');
//         return 'bar';
//     }
// }
// Object.assign(dest,src);
// console.log(dest);
// console.log(src.a);
// console.log(src.b);

// invoked src getter a
// invoked dest setter with param foo
// invoked src getter b
// { a: [Setter], b: 'bar' }

// invoked src getter a
// foo

// invoked src getter b
// bar

// let dest = {id:'dest'};
// Object.defineProperty(dest,'id',{
//     set(newValue){
//     console.log('dest--set-->'+newValue);
//     }
// })
// let result = Object.assign(dest,{id:'src1',userName:'foo'},{id:'src2',age:15});
// console.log(result);

// dest--set-->src1
// dest--set-->src2
// { id: [Setter], userName: 'foo', age: 15 }

// let dest = {};
// let src = {
//     a:'Smith',
//     get b(){
//       // Object.assign()在调用这个获取函数时会抛出错误
//       throw new Error();
//     },
//     c:'HAHAHA'
// }
// try{
//     Object.assign(dest,src);
// }catch(err){
//     console.log(dest);
//     console.log(err);
// }

// 这些是===符合预期的情况
// console.log(true === 1);//false
// console.log({} === {});//false
// console.log('2' === 2);//false
// // 这些情况在不同 JavaScript 引擎中表现不同，但仍被认为相等
// console.log(+0 === -0);//true
// console.log(+0 === 0);//true
// console.log(-0 === 0);//true
// //// 要确定 NaN 的相等性，必须使用极为讨厌的 isNaN()
// console.log(NaN === NaN);//false
// console.log(isNaN(NaN));//true
// //ECMAScript 6 规范新增了 Object.is()，这个方法与===很像，但同时也考虑到了上述边界情形
// console.log(Object.is(true,1));//false
// console.log(Object.is({},{}));//false
// console.log(Object.is('2',2));//false

// console.log(Object.is(+0,-0));//false
// console.log(Object.is(+0,0));//true
// console.log(Object.is(-0,0));//false

// console.log(Object.is(NaN,NaN));//true

// console.log('----------------------------------------------');
// function equal(value,...rest){
//     return Object.is(value,rest[0]) && (rest.length < 2 || equal(...rest));
// }
// console.log(equal(1,1,1,1,1));//true

// let username = 'Smith';
// let person = {
//     username,
// }
// console.log(person.username);//Smith

// function getUserName(uersname){
//     return {
//         username
//     }
// }
// console.log(getUserName(username).username);//Smith

//ES6之前给一个对象动态绑定属性的操作---必须先声明对象，然后使用中括号语法来添加属性。换句话说，不能在对象字面量中直接动态命名属性。
// let key1 = 'name';
// let key2 = 'age';
// let key3 = 'score';
// let person = {};
// person[key1] = 'alice';
// person[key2] = 25;
// person[key3] = '及格';
// console.log(person);//{ name: 'alice', age: 25, score: '及格' }
// //采用ES6的对象的可计算属性之后---就可以在对象字面量中完成动态属性赋值。中括号包围的对象属性键告诉运行时将其作为 JavaScript 表达式而不是字符串来求值：
// let person1 = {
//     [key1]:'smith',
//     [key2]:30,
//     [key3]:'优秀'
// };
// console.log(person1);//{ name: 'smith', age: 30, score: '优秀' }
// //可计算属性复杂操作
// const namekey = 'name';
// const ageKey = 'age';
// const jobKey = 'job';
// let uniqueToken = 0;
// function getUniqueKey(value){
//     return `${value}_${uniqueToken++}`;
// }
// let person2 = {
//     [getUniqueKey(namekey)]:'Tom',
//     [getUniqueKey(ageKey)]:'25',
//     [getUniqueKey(jobKey)]:'a computer',
// }
// console.log(person2);//{ name_0: 'Tom', age_1: '25', job_2: 'a computer' }

// //方法名简写
// let obj = {
//     show(){
//         console.log('hello world');
//     }
// }
// obj.show();//hello world
// //与set和get一起混用
// let student ={
//     age_:'',
//     set age(val){
//         console.log('------set',val);
//         this.age_ = val;
//     },
//     get age(){
//         console.log('-------get',this.age_);
//         return this.age_;
//     }
// }

// student.age = 25;
// console.log(student.age);
// // ------set 25
// // -------get 25
// // 25

// //与可计算属性一起使用

// let funcName = 'show';
// let teacher = {
//     [funcName](){
//         console.log('funcName--->',funcName);
//     }
// }
// teacher.show();//funcName---> show

